using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

namespace ZombieHigh2.BodySystem
{
    public abstract class Body
    {
        #region Member Variables
        Vector3 _position;
        Vector3 _velocity;
        BoundingBox _bbox;
        BoundingBox _localVerts;
        Boolean _gravity;
        Boolean _remove;
        Boolean _affectBodies;
        Boolean _bounce;
        protected float _coefficient;
        #endregion

        #region Properties
        public Boolean Bounce
        {
            get { return _bounce; }
            set { _bounce = value; }
        }

        public float Coefficient
        {
            get { return _coefficient; }
            set { _coefficient = value; }
        }

        public Vector3 Position
        {
            get { return _position; }
            set
            {
                _position = value;
                UpdateBBox();
            }
        }

        public Vector3 Velocity
        {
            get { return _velocity; }
            set { _velocity = value; }
        }

        public BoundingBox AABB
        {
            get { return _bbox; }
        }

        public float Width
        {
            get { return _bbox.Max.X - _bbox.Min.X; }
        }

        public float Height
        {
            get { return _bbox.Max.Y - _bbox.Min.Y; }
        }

        public float Depth
        {
            get { return _bbox.Max.Z - _bbox.Min.Z; }
        }

        public Vector3 Center
        {
            get { return new Vector3(_position.X + Width/2, _position.Y - Height/2, _position.Z + Depth/2); }
        }

        public float X
        {
            get { return _position.X; }
            set
            {
                _position.X = value;
                UpdateBBox();
            }
        }

        public float Y
        {
            get { return _position.Y; }
            set
            {
                _position.Y = value;
                UpdateBBox();
            }
        }

        public float Z
        {
            get { return _position.Z; }
            set
            {
                _position.Z = value;
                UpdateBBox();
            }
        }

        public Boolean Gravity
        {
            get { return _gravity; }
            set
            {
                _gravity = value;
            }
        }

        public Boolean Remove
        {
            get { return _remove; }
            set { _remove = value; }
        }

        public Boolean AffectBodies
        {
            get { return _affectBodies; }
            set { _affectBodies = value; }
        }
        #endregion

        private void UpdateBBox()
        {
            _bbox.Min = _localVerts.Min + _position;
            _bbox.Max = _localVerts.Max + _position;
        }

        public void SetNewBBox(BoundingBox size)
        {
            _bbox.Min = size.Min;
            _bbox.Max = size.Max;
            _localVerts = new BoundingBox(_bbox.Min, _bbox.Max);
        }

        public Body()
        {
            _gravity = false;
            _remove = false;
            _affectBodies = true;
            _bounce = false;
            _coefficient = 0f;
        }

        public Body(BoundingBox bbox)
        {
            _gravity = false;
            _localVerts = new BoundingBox(bbox.Min, bbox.Max);
            _bbox = new BoundingBox(bbox.Min, bbox.Max);
            _remove = false;
            _affectBodies = true;
            _bounce = false;
            _coefficient = 0f;
        }

        #region CallBack Methods
        public virtual void OnContact(Body body)
        {
        }

        public virtual void OnGroundHit()
        {
        }
        #endregion
    }
}
